package com.godenwater.yanyu;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.godenwater.yanyu.body.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.godenwater.yanyu.utils.ByteUtil;

public class YYParser {

    /**
     * 燕禹的RTU测站编码有借位的现象，需要进行补位计算
     *
     * @param centerAddr
     * @param stationAddr
     * @return
     */
    public static int parseStcd(byte[] centerAddr, byte[] stationAddr) {

        if (centerAddr[0] == (byte) 0xFE || centerAddr[0] == (byte) 0xFC) {
            //根据实际情况添加随州FC作为中心站地址，解析站号
            //有一类测站信息，中心站为FE时，不借位
            return (stationAddr[0] & 0xff);
        } else {
            // int datalen = (int) (data >> 3 & 0x1F);// 获取前五位的数据
            int decimal = (int) (centerAddr[0] & 0x07); // 获取后三位的小数点位数
            // stationAddr[0];
            // return ByteUtil.bytesToUbyte(stationAddr);

            return ((centerAddr[0] & 0x07) << 8) | (stationAddr[0] & 0xff);// 将中心站地址的右三位进行并入计算
        }
    }

    /**
     * 构造“报文结束符”
     *
     * @param mode
     * @param bodyEndBit
     * @param keep
     * @return
     */
    public static byte parseEndBit(String mode, byte bodyEndBit, boolean keep) {

        byte replyStartBit = Symbol.EOT;

        if (mode.equals("M2")) {
            // 关键点：针对ETB方式，需多次回复确认
            // 其上行帧报文结束符为ETB/ETX
            // 下行帧为“确认”帧，报文结束符为EOT/ESC。
            if (bodyEndBit == Symbol.ETB) {
                replyStartBit = Symbol.ACK;
            }
            if (bodyEndBit == Symbol.ETX) {
                if (keep == true) {
                    replyStartBit = Symbol.ENQ;// 保持在线
                } else {
                    replyStartBit = Symbol.EOT;
                }
            }
        }
        if (mode.equals("M3")) {
            // 关键点：仅回复一次确认包
            // 其上行帧报文结束符为ETB/ETX（收到NAK的重发包用ETX）；
            // 下行帧为“确认/否认”帧，报文结束符为EOT/NAK/ESC

            // ----data------第一帧报文ETB-------
            // .................................|
            // ----data------第二帧报文ETB-------
            // .................................|
            // ----data------第三帧报文ETB-------
            // .................................|
            // ----data------最后一帧报文ETX-------
            // --正确，则发EOT确认;错误，则发送NAK结束
            if (bodyEndBit == Symbol.ETB) {
                replyStartBit = Symbol.ACK;
            }

            if (bodyEndBit == Symbol.ETX) {
                if (keep == true) {
                    replyStartBit = Symbol.ENQ;// 保持在线
                } else {
                    replyStartBit = Symbol.EOT;
                }
            }

        }
        if (mode.equals("M4")) {
            // 关键点：其实M4模式就是M2模式与M3模式的结合。发起端是中心站，接收到的数据不存在此种模式
            // 下行帧为“查询/确认”帧，报文结束符为ENQ/ACK/EOT；
            // 上行帧为响应帧，报文结束符为ETB/ETX。

        }

        // 总结：
        // --------报文起始符，只有两种STX/SYN。SYN只有在多包传输正文时使用
        // ----上行报文结束符，只有两种ETB/ETX。ETB后续有报文（与起始符SYN结合使用），ETX后续无报文

        return replyStartBit;
    }

    // --------------------------------------------------------------------
    //
    //
    // ---------------------------------------------------------------------

    public static Up0EBody parse0EBody(byte[] bytes) throws Exception {

        Up0EBody body = new Up0EBody();
        int pos = 0;

        // 发报时间
        byte[] sendDate = new byte[5];
        System.arraycopy(bytes, pos, sendDate, 0, sendDate.length);
        pos = pos + sendDate.length;
        body.setSendDate(ByteUtil.bcd2Str(bytes));

        // 雨量累计值：2字节16进制数，0000H------0FFFH。
        byte[] f1 = new byte[2];
        System.arraycopy(bytes, pos, f1, 0, f1.length);
        body.setF1(f1);
        pos = pos + f1.length;

        // 时段雨量：2字节16进制数， 0000H------0FFFH。
        byte[] f2 = new byte[2];
        System.arraycopy(bytes, pos, f2, 0, f2.length);
        body.setF2(f2);
        pos = pos + f2.length;

        // 日雨量：2字节16进制数，0000H------0FFFH。
        byte[] f3 = new byte[2];
        System.arraycopy(bytes, pos, f3, 0, f3.length);
        body.setF3(f3);
        pos = pos + f3.length;

        // 雨量5： 每小时内间隔5分钟的雨量，单字节16进制数，12组共12字节。
        byte[] f4 = new byte[12];
        System.arraycopy(bytes, pos, f4, 0, f4.length);
        body.setF4(f4);
        pos = pos + f4.length;

        if (bytes.length != 46) {
            //不是雨量里包含的水位10个的情况
            // 水位5： 每小时内间隔5分钟的水位，双字节16进制数，12组共24字节。
            byte[] f5 = new byte[24];
            System.arraycopy(bytes, pos, f5, 0, f5.length);
            body.setF5(f5);
            pos = pos + f5.length;

            // 电压：2字节BCD码，表示XX。XX伏特。
            byte[] f6 = new byte[2];
            System.arraycopy(bytes, pos, f6, 0, f6.length);
            body.setF6(f6);
            pos = pos + f6.length;

            // 风速：2字节16进制数。
            byte[] f7 = new byte[2];
            System.arraycopy(bytes, pos, f7, 0, f7.length);
            body.setF7(f7);
            pos = pos + f7.length;

            // 风向：2字节16进制数。
            byte[] f8 = new byte[2];
            System.arraycopy(bytes, pos, f8, 0, f8.length);
            body.setF8(f8);
            pos = pos + f8.length;

            // 温度：2字节16进制数。
            byte[] f9 = new byte[2];
            System.arraycopy(bytes, pos, f9, 0, f9.length);
            body.setF9(f9);
            pos = pos + f9.length;

            // 湿度：2字节16进制数。
            byte[] f10 = new byte[2];
            System.arraycopy(bytes, pos, f10, 0, f10.length);
            body.setF10(f10);
            pos = pos + f10.length;

            // 气压：2字节16进制数。
            byte[] f11 = new byte[2];
            System.arraycopy(bytes, pos, f11, 0, f11.length);
            body.setF11(f11);
            pos = pos + f11.length;
        } else {
            //雨量里水位是10个的情况
            // 水位5： 每小时内间隔5分钟的水位，双字节16进制数，12组共24字节。
            byte[] f5 = new byte[20];
            System.arraycopy(bytes, pos, f5, 0, f5.length);
            body.setF5(f5);
            pos = pos + f5.length;
            // 电压：2字节BCD码，表示XX。XX伏特。
            byte[] f6 = new byte[2];
            System.arraycopy(bytes, pos, f6, 0, f6.length);
            body.setF6(f6);
            pos = pos + f6.length;
        }
        // 状态：备用
        byte[] f12 = new byte[1];
        System.arraycopy(bytes, pos, f12, 0, f12.length);
        body.setF12(f12);
        pos = pos + f12.length;

        return body;
    }

    public static Up0E10Body parse0E10Body(byte[] bytes) throws Exception {

        Up0E10Body body = new Up0E10Body();
        int pos = 0;

        // 发报时间
        byte[] sendDate = new byte[5];
        System.arraycopy(bytes, pos, sendDate, 0, sendDate.length);
        pos = pos + sendDate.length;
        body.setSendDate(ByteUtil.bcd2Str(bytes));

        // 雨量累计值：2字节16进制数，0000H------0FFFH。
        byte[] f1 = new byte[2];
        System.arraycopy(bytes, pos, f1, 0, f1.length);
        body.setF1(f1);
        pos = pos + f1.length;

        // 时段雨量：2字节16进制数， 0000H------0FFFH。
        byte[] f2 = new byte[2];
        System.arraycopy(bytes, pos, f2, 0, f2.length);
        body.setF2(f2);
        pos = pos + f2.length;

        // 日雨量：2字节16进制数，0000H------0FFFH。
        byte[] f3 = new byte[2];
        System.arraycopy(bytes, pos, f3, 0, f3.length);
        body.setF3(f3);
        pos = pos + f3.length;

        // 雨量5： 每小时内间隔5分钟的雨量，单字节16进制数，12组共12字节。
        byte[] f4 = new byte[12];
        System.arraycopy(bytes, pos, f4, 0, f4.length);
        body.setF4(f4);
        pos = pos + f4.length;

        // 水位5： 每小时内间隔5分钟的水位，双字节16进制数，12组共24字节。
        byte[] f5 = new byte[24];
        System.arraycopy(bytes, pos, f5, 0, f5.length);
        body.setF5(f5);
        pos = pos + f5.length;

        // 电压：2字节BCD码，表示XX。XX伏特。
        byte[] f6 = new byte[2];
        System.arraycopy(bytes, pos, f6, 0, f6.length);
        body.setF6(f6);
        pos = pos + f6.length;

        //风暴潮数据10字节数据
        byte[] f7 = new byte[10];
        System.arraycopy(bytes, pos, f7, 0, f7.length);
        body.setF7(f7);
        pos = pos + f7.length;

        //闸位数据，1个闸位数据3字节，闸位数据3*8=24字节。
        byte[] f8 = new byte[24];
        System.arraycopy(bytes, pos, f8, 0, f8.length);
        body.setF8(f8);
        pos = pos + f8.length;


        return body;
    }


    public static Up0E16Body parse0E16Body(byte[] bytes) throws Exception {

        Up0E16Body body = new Up0E16Body();
        int pos = 0;

        // 发报时间
        byte[] sendDate = new byte[5];
        System.arraycopy(bytes, pos, sendDate, 0, sendDate.length);
        pos = pos + sendDate.length;
        body.setSendDate(ByteUtil.bcd2Str(bytes));

        // 雨量累计值：2字节16进制数，0000H------0FFFH。
        byte[] f1 = new byte[2];
        System.arraycopy(bytes, pos, f1, 0, f1.length);
        body.setF1(f1);
        pos = pos + f1.length;

        // 时段雨量：2字节16进制数， 0000H------0FFFH。
        byte[] f2 = new byte[2];
        System.arraycopy(bytes, pos, f2, 0, f2.length);
        body.setF2(f2);
        pos = pos + f2.length;

        // 日雨量：2字节16进制数，0000H------0FFFH。
        byte[] f3 = new byte[2];
        System.arraycopy(bytes, pos, f3, 0, f3.length);
        body.setF3(f3);
        pos = pos + f3.length;

        // 雨量5： 每小时内间隔5分钟的雨量，单字节16进制数，12组共12字节。
        byte[] f4 = new byte[12];
        System.arraycopy(bytes, pos, f4, 0, f4.length);
        body.setF4(f4);
        pos = pos + f4.length;

        // 水位5： 每小时内间隔5分钟的水位，双字节16进制数，12组共24字节。
        byte[] f5 = new byte[24];
        System.arraycopy(bytes, pos, f5, 0, f5.length);
        body.setF5(f5);
        pos = pos + f5.length;

        // 电压：2字节BCD码，表示XX。XX伏特。
        byte[] f6 = new byte[2];
        System.arraycopy(bytes, pos, f6, 0, f6.length);
        body.setF6(f6);
        pos = pos + f6.length;

        //风暴潮数据10字节数据
        byte[] f7 = new byte[10];
        System.arraycopy(bytes, pos, f7, 0, f7.length);
        body.setF7(f7);
        pos = pos + f7.length;

        //流速流量数据，12*8=96字节。
        byte[] f8 = new byte[96];
        System.arraycopy(bytes, pos, f8, 0, f8.length);
        body.setF8(f8);

        return body;
    }

    public static Up0E17Body parse0E17Body(byte[] bytes) throws Exception {

        Up0E17Body body = new Up0E17Body();
        int pos = 0;

        // 发报时间
        byte[] sendDate = new byte[5];
        System.arraycopy(bytes, pos, sendDate, 0, sendDate.length);
        pos = pos + sendDate.length;
        body.setSendDate(ByteUtil.bcd2Str(bytes));

        // 雨量累计值：2字节16进制数，0000H------0FFFH。
        byte[] f1 = new byte[2];
        System.arraycopy(bytes, pos, f1, 0, f1.length);
        body.setF1(f1);
        pos = pos + f1.length;

        // 时段雨量：2字节16进制数， 0000H------0FFFH。
        byte[] f2 = new byte[2];
        System.arraycopy(bytes, pos, f2, 0, f2.length);
        body.setF2(f2);
        pos = pos + f2.length;

        // 日雨量：2字节16进制数，0000H------0FFFH。
        byte[] f3 = new byte[2];
        System.arraycopy(bytes, pos, f3, 0, f3.length);
        body.setF3(f3);
        pos = pos + f3.length;

        // 雨量5： 每小时内间隔5分钟的雨量，单字节16进制数，12组共12字节。
        byte[] f4 = new byte[12];
        System.arraycopy(bytes, pos, f4, 0, f4.length);
        body.setF4(f4);
        pos = pos + f4.length;

        // 水位5： 每小时内间隔5分钟的水位，双字节16进制数，12组共24字节。
        byte[] f5 = new byte[24];
        System.arraycopy(bytes, pos, f5, 0, f5.length);
        body.setF5(f5);
        pos = pos + f5.length;

        // 电压：2字节BCD码，表示XX。XX伏特。
        byte[] f6 = new byte[2];
        System.arraycopy(bytes, pos, f6, 0, f6.length);
        body.setF6(f6);
        pos = pos + f6.length;

        //风暴潮数据10字节数据
        byte[] f7 = new byte[10];
        System.arraycopy(bytes, pos, f7, 0, f7.length);
        body.setF7(f7);
        pos = pos + f7.length;

        //1字节。
        byte[] f8 = new byte[1];
        System.arraycopy(bytes, pos, f8, 0, f8.length);
        body.setF8(f8);
        pos = pos + f8.length;

        //流速流量数据，12*8=96字节。
        byte[] f9 = new byte[96];
        System.arraycopy(bytes, pos, f9, 0, f9.length);
        body.setF9(f9);
        pos = pos + f9.length;


        return body;
    }

    public static Up0E14Body parse0E14Body(byte[] bytes) throws Exception {

    	Up0E14Body body = new Up0E14Body();
        int pos = 0;

        // 发报时间
        byte[] sendDate = new byte[5];
        System.arraycopy(bytes, pos, sendDate, 0, sendDate.length);
        pos = pos + sendDate.length;
        body.setSendDate(ByteUtil.bcd2Str(bytes));

        // 雨量累计值：2字节16进制数，0000H------0FFFH。
        byte[] f1 = new byte[2];
        System.arraycopy(bytes, pos, f1, 0, f1.length);
        body.setF1(f1);
        pos = pos + f1.length;

        // 时段雨量：2字节16进制数， 0000H------0FFFH。
        byte[] f2 = new byte[2];
        System.arraycopy(bytes, pos, f2, 0, f2.length);
        body.setF2(f2);
        pos = pos + f2.length;

        // 日雨量：2字节16进制数，0000H------0FFFH。
        byte[] f3 = new byte[2];
        System.arraycopy(bytes, pos, f3, 0, f3.length);
        body.setF3(f3);
        pos = pos + f3.length;

        // 雨量5： 每小时内间隔5分钟的雨量，单字节16进制数，12组共12字节。
        byte[] f4 = new byte[12];
        System.arraycopy(bytes, pos, f4, 0, f4.length);
        body.setF4(f4);
        pos = pos + f4.length;

        // 水位5： 每小时内间隔5分钟的水位，双字节16进制数，12组共24字节。
        byte[] f5 = new byte[24];
        System.arraycopy(bytes, pos, f5, 0, f5.length);
        body.setF5(f5);
        pos = pos + f5.length;

        // 电压：2字节BCD码，表示XX。XX伏特。
        byte[] f6 = new byte[2];
        System.arraycopy(bytes, pos, f6, 0, f6.length);
        body.setF6(f6);
        pos = pos + f6.length;

        //风暴潮数据10字节数据
        byte[] f7 = new byte[10];
        System.arraycopy(bytes, pos, f7, 0, f7.length);
        body.setF7(f7);
        pos = pos + f7.length;

        //日蒸发量数据，2字节。
        byte[] f9 = new byte[2];
        System.arraycopy(bytes, pos, f9, 0, f9.length);
        body.setF9(f9);
        pos = pos + f9.length;


        return body;
}

    /**
     * 特征为0Eh，表示正点发报。
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up0EBody parse0EBody(IMessageBody messageBody)
            throws Exception {
        byte[] bytes = messageBody.getContent();
        return parse0EBody(bytes);
    }

    /**
     * 特征为0Bh，表示雨量加报。
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up0EBody parse0BBody(IMessageBody messageBody)
            throws Exception {
        return (Up0EBody) parse0EBody(messageBody);
    }

    /**
     * 特征为09h，表示水位加报。
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up0EBody parse09Body(IMessageBody messageBody)
            throws Exception {
        return (Up0EBody) parse0EBody(messageBody);
    }

    /**
     * 特征为0Ch，表示测试信息。
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up0EBody parse0CBody(IMessageBody messageBody)
            throws Exception {
        return (Up0EBody) parse0EBody(messageBody);
    }

    /**
     * 05H为读配置命令特征码
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up05Body parse05Body(IMessageBody messageBody)
            throws Exception {
        byte[] bytes = messageBody.getContent();
        Up05Body body = new Up05Body();

        int pos = 0;
        // 发报时间
        byte[] sendDate = new byte[5];
        System.arraycopy(bytes, pos, sendDate, 0, sendDate.length);
        pos = pos + sendDate.length;
        body.setSendDate(ByteUtil.bcd2Str(bytes));

        // 时段(1)
        byte[] f1 = new byte[1];
        System.arraycopy(bytes, pos, f1, 0, f1.length);
        body.setF1(f1);
        pos = pos + f1.length;

        // 雨量加报阈值1(1)
        byte[] f2 = new byte[1];
        System.arraycopy(bytes, pos, f2, 0, f2.length);
        body.setF2(f2);
        pos = pos + f2.length;

        // 日起始时间(1)
        byte[] f3 = new byte[1];
        System.arraycopy(bytes, pos, f3, 0, f3.length);
        body.setF3(f3);
        pos = pos + f3.length;

        // 加报水位(2)
        byte[] f4 = new byte[2];
        System.arraycopy(bytes, pos, f4, 0, f4.length);
        body.setF4(f4);
        pos = pos + f4.length;

        // 加报水位以 上变化量(1)
        byte[] f5 = new byte[1];
        System.arraycopy(bytes, pos, f5, 0, f5.length);
        body.setF5(f5);
        pos = pos + f5.length;

        // 加报水位以下变化量(1)
        byte[] f6 = new byte[1];
        System.arraycopy(bytes, pos, f6, 0, f6.length);
        body.setF6(f6);
        pos = pos + f6.length;

        // 警戒水位(2)
        byte[] f7 = new byte[2];
        System.arraycopy(bytes, pos, f7, 0, f7.length);
        body.setF7(f7);
        pos = pos + f7.length;

        // 警戒水位以上发报 时间间隔(1)
        byte[] f8 = new byte[1];
        System.arraycopy(bytes, pos, f8, 0, f8.length);
        body.setF8(f8);
        pos = pos + f8.length;

        // 中心站号（2）
        byte[] f9 = new byte[2];
        System.arraycopy(bytes, pos, f9, 0, f9.length);
        body.setF9(f9);
        pos = pos + f9.length;

        // 中心手机号（6）
        byte[] f10 = new byte[6];
        System.arraycopy(bytes, pos, f10, 0, f10.length);
        body.setF10(f10);
        pos = pos + f10.length;

        // 中心电话号码（6）
        byte[] f11 = new byte[6];
        System.arraycopy(bytes, pos, f11, 0, f11.length);
        body.setF11(f11);
        pos = pos + f11.length;

        // 雨量加报阈值2（1）
        byte[] f12 = new byte[1];
        System.arraycopy(bytes, pos, f12, 0, f12.length);
        body.setF12(f12);
        pos = pos + f12.length;

        return body;
    }

    /**
     * 人工拍报（GPRS）
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up08Body parse08Body(IMessageBody messageBody)
            throws Exception {
        byte[] bytes = messageBody.getContent();
        Up08Body body = new Up08Body();

        int pos = 0;

        // System.out.println(">>>>>>>>>> " + ByteUtil.toHexString(data));

        return body;
    }

    /**
     * 水位固态数据
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up06Body parse06Body(String stcd, IMessageBody messageBody)
            throws Exception {
        byte[] bytes = messageBody.getContent();

        return parse06Body(stcd, bytes);
    }

    public static Up06Body parse06Body(String stcd, byte[] bytes)
            throws Exception {
        Up06Body body = new Up06Body();
        int pos = 0;
        int total = bytes.length;
        // 发包序列号
        byte[] serial = new byte[2];
        System.arraycopy(bytes, pos, serial, 0, serial.length);
        pos = pos + serial.length;
        body.setSerial(serial);

        Map<Date, String> data = new HashMap<Date, String>();

        for (int i = pos; i < total; ) {

            byte[] temp = new byte[2];
            System.arraycopy(bytes, pos, temp, 0, temp.length);
            pos = pos + temp.length;

            // 发包类型，如果是AAAAAA表示是水位固态起始时间
            if (Arrays.equals(temp, new byte[]{(byte) 0xAA, (byte) 0xAA})) {

                byte[] a6 = new byte[3];
                System.arraycopy(bytes, pos - temp.length, a6, 0, a6.length);
                pos = pos + a6.length - temp.length;

                // 起始日期
                byte[] startDate = new byte[3];
                System.arraycopy(bytes, pos, startDate, 0, startDate.length);
                pos = pos + startDate.length;
                // body.setStartDate(startDate);

                SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
                Date sDate = sdf.parse(ByteUtil.bcd2Str(startDate));

                YYStationSolid.updateRiverDate(stcd, sDate);

                // 起始时间
                byte[] startTime = new byte[2];
                System.arraycopy(bytes, pos, startTime, 0, startTime.length);
                pos = pos + startTime.length;

            } else {

                // 更新时间
                Date curDate = YYStationSolid.getRiverDate(stcd);
                if (curDate == null) curDate = new Date();
                curDate = DateUtils.addMinutes(curDate, 5);
                YYStationSolid.updateRiverDate(stcd, curDate);

                int val = ByteUtil.byte2ToUnsignedShort(temp);
                if (val != 65535) {// 相当于是FFFF，非法数据，不做处理
                    data.put(curDate,
                            YYBuilder.buildDot(String.valueOf(val), 2));// 需要将数据标示出小数点。
                }
            }

            i = pos;
        }

        // 显示有多少天，多少小时的数据
        // for (Map.Entry<Date, Integer> entry : data.entrySet()) {
        // SimpleDateFormat sdfDay = new SimpleDateFormat("yy-MM-dd HH:mm");
        // System.out.println(sdfDay.format(entry.getKey()) + "--->"
        // + entry.getValue());
        // }
        body.setData(data);

        return body;
    }

    /**
     * 雨量固态数据
     *
     * @param messageBody
     * @return
     * @throws Exception
     */
    public static Up0ABody parse0ABody(String stcd, IMessageBody messageBody)
            throws Exception {
        byte[] bytes = messageBody.getContent();

        return parse0ABody(stcd, bytes);
    }

    public static Up0ABody parse0ABody(String stcd, byte[] bytes)
            throws Exception {

        Up0ABody body = new Up0ABody();
        int pos = 0;
        int total = bytes.length;
        // 发包序列号
        byte[] serial = new byte[2];
        System.arraycopy(bytes, pos, serial, 0, serial.length);
        pos = pos + serial.length;
        body.setSerial(serial);

        Map<Date, Integer> data = new HashMap<Date, Integer>();

        for (int i = pos; i < total; ) {

            byte[] temp = new byte[2];
            // 发包类型，如果是BBBBBB表示是雨量固态起始时间
            System.arraycopy(bytes, pos, temp, 0, temp.length);
            pos = pos + temp.length;

            // temp[0] == 0xDD && temp[1] == 0xDD
            if (Arrays.equals(temp, new byte[]{(byte) 0xDD, (byte) 0xDD})) {

                // 发包类型，如果是BBBBBB表示是雨量固态起始时间
                byte[] d6 = new byte[3];
                System.arraycopy(bytes, pos - temp.length, d6, 0, d6.length);
                pos = pos + d6.length - temp.length;
                // body.setDddddd(d6);

                // System.out.println(">> YYParser dddd "
                // + ByteUtil.byteToHexString(d6));

                // 起始时间
                byte[] startDate = new byte[3];
                System.arraycopy(bytes, pos, startDate, 0, startDate.length);
                pos = pos + startDate.length;
                // body.setStartDate(startDate);

                YYStationSolid
                        .updateRainDate(stcd, ByteUtil.bcd2Str(startDate));
                YYStationSolid.updateRainTime(stcd, "0000");

                // System.out.println(">> YYParser parse0ABody1 "
                // + ByteUtil.bcd2Str(startDate));

            } else {

                // byte[] dd = new byte[2];
                // System.arraycopy(bytes, pos, dd, 0, dd.length);
                // pos = pos + dd.length;

                String tm = ByteUtil.bcd2Str(temp);
                String curDate = YYStationSolid.getRainDate(stcd);

                // 需要计算时间，将同一小时内的数据，写入到一个
                String tempTm = curDate + tm;
                SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
                Date tempDate = sdf.parse(tempTm);

                // 1.2还需要判断，时间切换到第二天的状况。
                String curTime = YYStationSolid.getRainTime(stcd);
                if (Integer.parseInt(tm) >= Integer.parseInt(curTime)) {
                    YYStationSolid.updateRainTime(stcd, tm);
                } else {
                    Calendar c = Calendar.getInstance();
                    c.setTime(tempDate);
                    c.add(Calendar.DATE, 1);

                    tempDate = c.getTime();
                    SimpleDateFormat sdfDay = new SimpleDateFormat("yyMMdd");
                    YYStationSolid.updateRainDate(stcd,
                            sdfDay.format(c.getTime()));
                    YYStationSolid.updateRainTime(stcd, "0000");
                }

                // 1.1先判断后两位是不是00，如果是00，则表示整点数据
                if (!StringUtils.substring(tm, 2, 4).equals("00")) {
                    // //如果不是00,则将数据写入到下一个小时
                    Calendar c = Calendar.getInstance();
                    c.setTime(tempDate);
                    c.add(11, 1);
                    c.set(12, 0);
                    c.set(13, 0);
                    tempDate = c.getTime();
                }

                // 1.3存储数据
                if (data.containsKey(tempDate)) {
                    int count = data.get(tempDate);
                    data.put(tempDate, count + 1);
                } else {
                    data.put(tempDate, 1);
                }

                // System.out.println(">> YYParser parse0ABody2 "
                // + ByteUtil.bcd2Str(temp) + " count " + data.get(tm));

            }

            i = pos;
        }

        // ------------------------------------------------------------
        // 显示有多少天，多少小时的数据
        for (Map.Entry<Date, Integer> entry : data.entrySet()) {
            SimpleDateFormat sdfDay = new SimpleDateFormat("yy-MM-dd HH:mm");
            System.out.println(sdfDay.format(entry.getKey()) + "--->"
                    + entry.getValue());
        }

        body.setData(data);

        return body;
    }

    public static void main(String[] args) {

        byte[] cc = new byte[]{(byte) 0x12,(byte) 0xd2};
        //System.out.println(parseStcd(cc ,cc));
        System.out.println( ((cc[0] & 0x07) << 8) | (cc[1] & 0xff));// 将中心站地址的右三位进行并入计算


        if (StringUtils.substring("1300", 2, 4).equals("00")) {
            System.out.println("OK 0000000");
        }

        byte[] xx = new byte[]{(byte) 0x20, (byte) 0x20, (byte) 0x20, (byte) 0x31, (byte) 0x2E, (byte) 0x37, (byte) 0x34, (byte) 0x33};
        System.out.println(">> xxx" + new String(xx));

        byte[] yy = new byte[]{(byte) 0x42, (byte) 0x17, (byte) 0x23, (byte) 0x44};
        System.out.println(">> yyy" + ByteUtil.bytesToInt(yy));

        byte[] r = new byte[]{(byte) 0x03, (byte) 0xF8};

        System.out.println("river " + ByteUtil.byte2ToUnsignedShort(r));

        String hex = "DDDD";
        byte[] bb = ByteUtil.HexStringToBinary(hex);

        if (Arrays.equals(bb, new byte[]{(byte) 0xDD, (byte) 0xDD})) {
            System.out.println("OK");
        }

        System.out.println(ByteUtil.toHexString(bb));

        byte[] stationBytes = ByteUtil.uintToBytes(255);

        System.out.println(">> stcd is " + ByteUtil.bytesToInt(stationBytes));
        System.out.println(">> stcd is "
                + YYParser.parseStcd(new byte[]{0x01}, stationBytes));


        System.out.println(0x77 & 0xff);
    }

}
